<template>
	<div class="prompts-page">
		<div class="header">
			<h2>提示词库</h2>
			<p>自定义AI对话提示词</p>
		</div>

		<div class="head">
			<el-input v-model="searchQuery" placeholder="搜索提示词..." clearable class="search-input" />
			<div class="spacer"/>
			<el-button type="primary" class="create-btn" @click="openCreate">新建提示词</el-button>
		</div>

		<div class="grid">
			<el-card v-for="p in visiblePrompts" :key="p.system_prompt_id" class="prompt-card" shadow="hover">
				<div class="card-head">
					<div class="avatar">✨</div>
					<div class="meta">
						<div class="title" :title="snippet(p.title)">{{ snippet(p.title) }}</div>
						<div class="time">{{ fmt(p.updated_time) }}</div>
					</div>
					<div class="ops">
						<el-dropdown @click.stop trigger="click">
							<span class="more-btn" @click.stop>
								<el-icon><MoreFilled /></el-icon>
							</span>
							<template #dropdown>
								<el-dropdown-menu>
									<el-dropdown-item @click.stop="onEdit(p)">编辑</el-dropdown-item>
									<el-dropdown-item divided @click.stop="onDelete(p)"><span class="danger">删除</span></el-dropdown-item>
								</el-dropdown-menu>
							</template>
						</el-dropdown>
					</div>
				</div>
				<div v-if="p.enable_context" class="badge">支持上下文</div>
				<div class="content" :title="p.content">{{ p.content }}</div>
			</el-card>
		</div>

		<div class="pager">
			<el-pagination
				background
				layout="prev, pager, next"
				:current-page="page"
				:page-size="pageSize"
				:total="total"
				@current-change="onPageChange"
			/>
		</div>

		<el-dialog v-model="editVisible" :title="editing ? '编辑提示词' : '新建提示词'" width="720px" append-to-body>
			<el-form label-position="top" class="form">
				<el-form-item label="提示词名称">
					<el-input v-model="form.title" maxlength="64" placeholder="例如：客服-严谨-简洁" />
				</el-form-item>
				<el-form-item label="提示词内容">
					<el-input
						v-model="form.content"
						type="textarea"
						:autosize="{ minRows: 10, maxRows: 20 }"
						maxlength="4000"
						show-word-limit
						placeholder="请输入系统提示词（用于设定 AI 的人格、语气、约束、风格等）"
					/>
				</el-form-item>
				<el-form-item label="启用上下文RAG">
					<el-switch v-model="form.enable_context" />
				</el-form-item>
				<el-form-item v-if="form.enable_context" label="上下文占位符">
					<el-input v-model="form.context_placeholder" placeholder="例如：[CONTEXT]" />
					<div class="hint">在提示词中用占位符标记上下文插入位置，发送时将自动替换为召回内容</div>
				</el-form-item>
			</el-form>
			<template #footer>
				<el-button @click="editVisible=false">取消</el-button>
				<el-button type="primary" :loading="saving" @click="save">{{ editing ? '保存' : '创建' }}</el-button>
			</template>
		</el-dialog>
	</div>
</template>

<script>
import { apiService } from '@/services/api'
import { MoreFilled } from '@element-plus/icons-vue'

export default {
	name: 'PromptsIndex',
	components: { MoreFilled },
	data() {
		return {
			loading: false,
			prompts: [],
			page: 1,
			pageSize: 12,
			total: 0,
			editVisible: false,
			editing: false,
			saving: false,
			currentId: null,
			form: { title: '', content: '', enable_context: false, context_placeholder: '[CONTEXT]' },
			searchQuery: ''
		}
	},
	computed: {
		visiblePrompts(){
			const q = (this.searchQuery || '').trim().toLowerCase()
			if (!q) return this.prompts
			return (this.prompts || []).filter(p => {
				const t = (p.title || '').toLowerCase()
				const c = (p.content || '').toLowerCase()
				return t.includes(q) || c.includes(q)
			})
		}
	},
	mounted() {
		this.fetch()
	},
	methods: {
		async fetch() {
			this.loading = true
			try {
				const res = await apiService.listSystemPrompts(this.page, this.pageSize)
				this.prompts = res.prompts || []
				this.total = res.total_count || 0
			} catch (e) { /* ignore */ }
			finally { this.loading = false }
		},
		snippet(text) {
			const t = (text || '').trim().replace(/\s+/g, ' ')
			return t.length > 30 ? t.slice(0, 30) + '…' : t
		},
		fmt(t) {
			try{ const d=new Date(t); if(isNaN(d)) return ''; return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')} ${String(d.getHours()).padStart(2,'0')}:${String(d.getMinutes()).padStart(2,'0')}` }catch(_){ return '' }
		},
		onPageChange(p){ this.page = p; this.fetch() },
		openCreate(){ this.editing=false; this.currentId=null; this.form={ title: '', content: '', enable_context: false, context_placeholder: '[CONTEXT]' }; this.editVisible=true },
		onEdit(p){ this.editing=true; this.currentId=p.system_prompt_id; this.form={ title: p.title || '', content: p.content || '', enable_context: !!p.enable_context, context_placeholder: p.context_placeholder || '[CONTEXT]' }; this.editVisible=true },
		async save(){
			if (!(this.form.content || '').trim()) return
			this.saving = true
			try{
				if (this.editing && this.currentId){
					await apiService.updateSystemPrompt(this.currentId, this.form.title || '', this.form.content, this.form.enable_context, this.form.context_placeholder)
					this.$message.success('已保存')
				}
				else{
					await apiService.createSystemPrompt(this.form.title || '', this.form.content, this.form.enable_context, this.form.context_placeholder)
					this.$message.success('已创建')
				}
				this.editVisible=false
				this.fetch()
			}catch(e){ /* ignore */ }
			finally{ this.saving=false }
		},
		async onDelete(p){
			try{
				await this.$confirm('确认删除该提示词？', '提示', { type: 'warning' })
				await apiService.deleteSystemPrompt(p.system_prompt_id)
				this.$message.success('已删除')
				this.fetch()
			}catch(_){ /* canceled */ }
		}
	}
}
</script>

<style scoped>
.prompts-page{ padding: 16px 24px; --pm-accent:#7b8cff; --pm-accent-2:#4dabf7; --pm-bg: linear-gradient(180deg, rgba(123,140,255,.06), rgba(77,171,247,.05)); background: var(--pm-bg); height: 100%; display: flex; flex-direction: column; }
.header{
  padding: 12px 14px;
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(77,171,247,0.08), rgba(77,171,247,0.02));
  border: 1px solid rgba(77,171,247,0.15);
  margin-bottom: 20px;
}
.header h2{
  font-size: 22px;
  margin-bottom: 6px;
  background-image: linear-gradient(120deg, rgba(77,171,247,0.35), rgba(77,171,247,0));
  background-size: 100% 40%;
  background-repeat: no-repeat;
  background-position: 0 80%;
}
.header p{
  color: var(--muted);
  font-size: 14px;
}
.head{ display:flex; align-items:center; margin-bottom: 12px; }
.search-input{ max-width: 320px; }
.spacer{ flex: 1; }
.create-btn{ border-radius: 999px; padding: 0 18px; font-weight: 700; box-shadow: 0 10px 24px rgba(61,85,236,.28); }
.create-btn:hover{ filter: brightness(1.05); box-shadow: 0 12px 28px rgba(61,85,236,.32); }

.intro{ margin-bottom: 12px; border-radius: 14px; border: 1px solid var(--el-border-color); background: #fff; transition: box-shadow .28s ease, border-color .28s ease; }
.intro:hover{ border-color: var(--pm-accent); box-shadow: 0 12px 28px rgba(64, 158, 255, 0.14); }
.intro-title{ font-weight: 800; font-size: 16px; }
.intro-sub{ color: var(--el-text-color-secondary); margin-top: 6px; }

.grid{ display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; align-items: start; align-content: start; flex: 1; overflow: auto; }
@media (max-width: 1280px){ .grid{ grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 860px){ .grid{ grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px){ .grid{ grid-template-columns: 1fr; } }

.prompt-card{ border: 1px solid var(--el-border-color); border-radius: 14px; background: #fff; transition: box-shadow .24s ease, border-color .24s ease; display: flex; flex-direction: column; height: 150px; }
.prompt-card:hover{ border-color: var(--pm-accent); box-shadow: 0 12px 28px rgba(64, 158, 255, 0.12); }
.prompt-card .card-head{ display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
.prompt-card .avatar{ width: 36px; height: 36px; border-radius: 10px; background: linear-gradient(135deg, rgba(123,140,255,.2), rgba(77,171,247,.2)); display:flex; align-items:center; justify-content:center; border: 1px solid var(--el-border-color); }
.prompt-card .meta{ display:flex; flex-direction: column; min-width: 0; flex: 1; }
.prompt-card .meta .title{ font-weight: 800; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; font-size: 15px; }
.prompt-card .meta .time{ font-size: 12px; color: var(--el-text-color-secondary); margin-top: 2px; }
.prompt-card .ops{ position: relative; }
.prompt-card .more-btn{ display:inline-flex; align-items:center; justify-content:center; width: 28px; height: 28px; border-radius: 50%; background: #fff; border: 1px solid var(--el-border-color); color: var(--el-text-color-secondary); box-shadow: 0 2px 10px rgba(16,24,40,.04); cursor: pointer; }
.prompt-card .more-btn:hover{ background: rgba(77,171,247,0.08); color: var(--pm-accent); }
.prompt-card .content{ color: var(--el-text-color-regular); white-space: pre-wrap; line-height: 1.7; flex: 1; overflow: hidden; mask-image: linear-gradient(180deg, #000 120px, rgba(0,0,0,0) 160px); }
.badge{ position: absolute; top: 10px; right: 10px; background: rgba(61,85,236,.12); color: #3d55ec; padding: 2px 8px; border-radius: 12px; font-size: 12px; }
.hint{ color: var(--muted); font-size: 12px; margin-left: 8px; }
.danger{ color: #ef4444; }

.pager{ display:flex; justify-content:center; padding-top: 10px; }

/* AI风格按钮 */
.prompts-page :deep(.el-button){ background-color: var(--accent); border:none; color:#fff; box-shadow: 0 6px 18px rgba(61,85,236,.25); }
.prompts-page :deep(.el-button:hover){ filter: brightness(1.05); }
.prompts-page :deep(.el-button.is-link){ background-color: var(--accent); color:#fff; padding: 6px 12px; border-radius: 6px; }
</style> 